46. 全排列
46. 全排列
Similar Question
Solution Tips
方案一: 回溯 + N 叉树
本质就是每次删除, rest 越来越少, 从 index 0 开始遍历, 越遍历越少
var permute = function (nums) {
const res = [];
dfs([], nums);
return res;
function dfs(chosen, rest) {
if (chosen.length === nums.length) {
res.push([...chosen])
return;
}
if (curIndex > rest.length - 1) {
return;
}
// index 每次都是从 0 开始
for (let i = 0; i < rest.length; i++) {
chosen.push(rest[i])
// 删除 i
const newRest = rest.slice(0, i).concat(rest.slice(i + 1));
dfs(chosen, newRest);
chosen.pop();
}
}
}
console.log(permute([1,2,3]))
方案二: 回溯 + 二元思路
var permute = function (nums) {
const res = [];
dfs([], nums, 0);
return res;
function dfs(chosen, rest, curIndex) {
if (chosen.length === nums.length) {
res.push([...chosen])
return;
}
if (curIndex > rest.length - 1) {
return;
}
// 选了
chosen.push(rest[curIndex])
const newRest = rest.slice(0, curIndex).concat(rest.slice(curIndex + 1));
dfs(chosen, newRest, 0);
chosen.pop();
// 没选
dfs(chosen, rest, curIndex + 1);
}
}
console.log(permute([1,2,3]))
方案三: 使用 Used 数组
var permute = function(nums) {
const res = [], path = [];
backtracking(nums, nums.length, []);
return res;
function backtracking(n, k, used) {
if(path.length === k) {
res.push(Array.from(path));
return;
}
for (let i = 0; i < k; i++ ) {
if(used[i]) continue;
path.push(n[i]);
used[i] = true; // 同支
backtracking(n, k, used);
path.pop();
used[i] = false;
}
}
};
方案四: 利用已经排列的空间
每次将使用过的数字交换到最前面, 每次都从 newIndex 开始遍历, 就可以节省一下空间复杂度
参考官方题解: Loading Question... - 力扣(LeetCode)
可以用这个思路去优化二元方案里的剪枝策略